use crate::physical_plan::PhysicalPlanExprArg;
use crate::data_frame::{value::RealValue};
use crate::run_plan::{HandResult};
use crate::lazy_static::__Deref;
use std::sync::Arc;
use crate::data_frame::single_data::SingleData;

pub fn set(args: &[Box<PhysicalPlanExprArg>], data: &mut SingleData) -> HandResult {
    if args.len() == 2{
        let left = &args[0];
        let right = &args[1];

            if let PhysicalPlanExprArg::ElementValue(left) = left.deref() {
                match right.deref() {
                    PhysicalPlanExprArg::ConfValue(_right) => {
                        trace!("add args right cannot be ConfValue");
                        return HandResult::Err(());
                    },
                    PhysicalPlanExprArg::RealValue(right) => {
                        let mut tmp_data = data.data.deref().clone();

                        let res = tmp_data.set_key_value(left, right.clone());
                        data.data = Arc::from(tmp_data);

                        return res;
                    },
                    PhysicalPlanExprArg::ElementValue(right) => {
                        let mut tmp_data = data.data.deref().clone();

                        let right = &data.data.get_key_value(right)?;
                        let res = tmp_data.set_key_value(left, right.clone());
                        data.data = Arc::from(tmp_data);

                        return res;
                    },
                }
        }else{
            return HandResult::Err(());
        }
    }else{
        return HandResult::Err(());
    }
}

pub fn del(args: &[Box<PhysicalPlanExprArg>], data: &mut SingleData) -> HandResult {

    for t in args.iter(){
        match t.deref(){
            PhysicalPlanExprArg::ElementValue(t) => {
                let mut tmp_data = data.data.deref().clone();

                let res = tmp_data.delete_key(&t);

                data.data = Arc::from(tmp_data);
                return res;
            },
            PhysicalPlanExprArg::RealValue(_) => {
                return HandResult::Err(());
            },
            PhysicalPlanExprArg::ConfValue(_) => {
                return HandResult::Err(());
            },
        }
    }

    return HandResult::Ok(RealValue::None);
}